#pragma once
#include <iostream>
#include <assert.h>

using namespace std;

namespace zzzyh
{
	class string
	{
	public:
		typedef char* iterator;
		typedef const char* const_iterator;
		/*string()
			:str(new char[1]{'\0'}),
			size(0),
			capacity(0)
		{}*/
		iterator begin() 
		{
			return _str;
		}
		iterator end()
		{
			return _str+_size;
		}
		const_iterator begin() const
		{
			return _str;
		}
		const_iterator end() const
		{
			return _str + _size;
		}
		string(const char * s="")
		{
			_size = strlen(s);
			_capacity = _size;
			_str = new char[_capacity+1];
			/*for (size_t i = 0; i <= size; i++)
			{
				str[i] = s[i];
			}*/
			strcpy(_str, s);
		}
		
		/*string(const string& s) {
			this->_capacity = s._capacity;
			this->_size = s._size;
			this->_str = new char[s._capacity+1];
			memcpy(this->_str, s._str, s._capacity + 1);
		}*/

		void swap(string& s) {
			std::swap(this->_str, s._str);
			std::swap(this->_size, s._size);
			std::swap(this->_capacity, s._capacity);
		}

		string(const string& s) {
			string tmp(s.c_str());
			this->swap(tmp);
		}

		~string() {
			delete[] _str;
		}

		const char* c_str() const
		{
			return _str;
		}

		size_t size() const
		{
			return _size;
		}

		size_t capacity() const
		{
			return _capacity;
		}

		const char& operator[](size_t pos) const
		{
			assert(pos < _size);
			return _str[pos];
		}

		char& operator[](size_t pos)
		{
			assert(pos < _size);
			return _str[pos];
		}

		void reserve(size_t n);
		void push_buck(char c);
		void append(const char* c);
		string& operator+=(char c);

		/*string& operator=(const string& s) {
			if (this == &s)
				return*this;
			delete[] this->_str;
			this->_capacity = s._capacity;
			this->_size = s._size;
			this->_str = new char[s._capacity + 1];
			memcpy(this->_str, s._str, s._capacity + 1);
			return *this;
		}*/

		string& operator=(const string& s) {
			if (this == &s)
				return*this;
			string tmp(s.c_str());
			this->swap(tmp);
			return *this;
		}

		string& operator=(string s) {
			this->swap(s);
			return *this;
		}

		void insert(size_t pos, char c);
		void insert(size_t pos, const char* c);

		void erase(size_t pos, size_t len=npos);

		size_t find(const char c,int pos=0);
		size_t find(const char* c, int pos = 0);

		string substr(size_t pos, size_t len = npos);

		void clear() {
			_str[0] = '\0';
			_size = 0;
		}

	private:
		char* _str=nullptr;
		size_t _size=0;
		size_t _capacity=0;

		static const size_t npos;
	};
	
	static bool operator<(const string& s1, const string& s2)
	{
		return strcmp(s1.c_str(), s2.c_str()) > 0;
	}
	static bool operator>(const string& s1, const string& s2) {
		return strcmp(s1.c_str(), s2.c_str()) < 0;
	}

	static bool operator==(const string& s1, const string& s2)
	{
		return strcmp(s1.c_str(), s2.c_str()) == 0;
	}
	static bool operator<=(const string& s1, const string& s2)
	{
		return s1 == s2 || s1 < s2;
	}
	static bool operator>=(const string& s1, const string& s2) {
		return s1 == s2 || s1 > s2;
	}

	static bool operator!=(const string& s1, const string& s2) {
		return strcmp(s1.c_str(), s2.c_str()) != 0;
	}
	static ostream& operator<<(ostream& out, const string& s) {
		out << s.c_str();
		return out;
	}
	static istream& operator>>(istream& in, string& s) {
		s.clear();
		char ch;
		ch=in.get();
		const int n = 256;
		char buf[256] = { 0 };
		int i = 0;
		while(ch != ' ' && ch != '\n') {
			//s += ch;
			buf[i++] = ch;
			if (i == n - 1) {
				buf[i++] = '\0';
				s.append(buf);
				i = 0;
			}
			ch = in.get();
		}
		if (i != 0) {
			buf[i++] = '\0';
			s.append(buf);
		}
		return in;
	}

	/*static istream& operator>>(istream& in, string& s) {
		s.clear();
		char ch;
		ch = in.get();
		
		while (ch != ' ' && ch != '\n') {
			s += ch;
			ch = in.get();
		}
		return in;
	}*/

}